﻿namespace MSRI.SmsSessions
{
    using MSRI.HelperClasses;
    using System;
    using System.Collections.Generic;
    using System.Reflection;

    public class SmsMenu
    {
        private string _ErrorString;
        private string _footer;
        private string _header;
        private List<SmsMenuItem> _Items;
        private string _keyTextSeparator;
        private int _MaxSmsBodyLength;
        private object _menuData;
        private int _moreCount;
        private string _MoreKey;
        private List<string> _stateList;

        public SmsMenu()
        {
            this._moreCount = 0;
            this._menuData = null;
            this._stateList = new List<string>();
            this._Items = new List<SmsMenuItem>();
            this._MoreKey = null;
            this._header = null;
            this._footer = null;
            this._ErrorString = "Error:Invalid Option";
            this._MaxSmsBodyLength = 160;
            this._keyTextSeparator = "-";
        }

        public SmsMenu(SmsMenu Menu)
        {
            this._moreCount = Menu.MoreCount;
            this._menuData = null;
            this._stateList = new List<string>(Menu.StateList);
            this._Items = new List<SmsMenuItem>(Menu.Items);
            this._MoreKey = Menu.MoreKey;
            this._header = Menu.Header;
            this._footer = Menu.Footer;
            this._ErrorString = Menu.ErrorMessage;
            this._MaxSmsBodyLength = Menu.MaxSmsBodyLength;
            this._keyTextSeparator = Menu.KeyTextSeparator;
        }

        public bool AddSubMenuItem(SmsMenuItem MenuItem)
        {
            if (this._Items == null)
            {
                this._Items = new List<SmsMenuItem>();
            }
            if (!this.ValidKey(MenuItem.Key) || ((MenuItem.AltKey != null) && !this.ValidKey(MenuItem.AltKey)))
            {
                throw new Exception("Error: The Key or AltKey you are trying to register is already in use");
            }
            this._Items.Add(MenuItem);
            return true;
        }

        public bool ClearSubMenuItems()
        {
            if (this._Items != null)
            {
                this._Items.Clear();
                this._moreCount = 0;
                return true;
            }
            return false;
        }

        private string GetString(int MaxLength, int start)
        {
            string str = "";
            MaxLength -= (this._footer == null) ? 0 : this._footer.Length;
            int num = start;
            str = (this._header == null) ? "" : (this._header + Environment.NewLine);
            string str2 = (this._MoreKey == null) ? "" : string.Format("{0}{1}More\n", this._MoreKey, this._keyTextSeparator);
            for (num = start; (num < this._Items.Count) && (str.Length < MaxLength); num++)
            {
                string str3 = string.Format("{0}{2}{1}\n", this._Items[num].Key, this._Items[num].Text, this._keyTextSeparator);
                if (num == (this._Items.Count - 1))
                {
                    if ((str.Length + str3.Length) > MaxLength)
                    {
                        this._moreCount = num;
                        str = str + str2;
                        break;
                    }
                    this._moreCount = num + 1;
                    str = str + str3;
                }
                else
                {
                    if (((str.Length + str3.Length) + str2.Length) > MaxLength)
                    {
                        this._moreCount = num;
                        str = str + str2;
                        break;
                    }
                    str = str + str3;
                }
            }
            return (str + ((this._footer == null) ? "" : this._footer));
        }

        public string More(int MaxLength)
        {
            if ((this._Items != null) && (this._moreCount != this._Items.Count))
            {
                return this.GetString(MaxLength, this._moreCount);
            }
            return this._ErrorString;
        }

        public SmsResponseClass ProcessMessage(object SessionData, SmsClass SmsItem)
        {
            SmsResponseClass class2;
            SmsMenuItem currentMenuItem = this.CurrentMenuItem;
            if (currentMenuItem == null)
            {
                if (SmsItem.Body == this._MoreKey)
                {
                    class2 = new SmsResponseClass(new SmsClass(SmsItem.Number, this.More(this.MaxSmsBodyLength)));
                }
                else if (this[SmsItem.Body] != null)
                {
                    currentMenuItem = this[SmsItem.Body];
                    if (currentMenuItem.Type == MenuItemEnum.CustomString)
                    {
                        class2 = new SmsResponseClass(new SmsClass(SmsItem.Number, currentMenuItem.ResponseString));
                        class2.SessionState = currentMenuItem.ResponseSessionState;
                    }
                    else if (currentMenuItem.Type == MenuItemEnum.CustomFunction)
                    {
                        this._stateList.Add(SmsItem.Body);
                        class2 = currentMenuItem.CallCustomFunction(SmsItem);
                    }
                    else
                    {
                        this._stateList.Add(SmsItem.Body);
                        this._moreCount = 0;
                        class2 = new SmsResponseClass(new SmsClass(SmsItem.Number, currentMenuItem.ToString(this.MaxSmsBodyLength)));
                    }
                }
                else
                {
                    class2 = new SmsResponseClass(new SmsClass(SmsItem.Number, this.ToString(this.MaxSmsBodyLength)));
                }
            }
            else if (currentMenuItem.Type == MenuItemEnum.CustomString)
            {
                class2 = new SmsResponseClass(new SmsClass(SmsItem.Number, currentMenuItem.ResponseString));
                class2.SessionState = currentMenuItem.ResponseSessionState;
            }
            else if (currentMenuItem.Type == MenuItemEnum.CustomFunction)
            {
                class2 = currentMenuItem.CallCustomFunction(SmsItem);
            }
            else if (SmsItem.Body == currentMenuItem.MoreKey)
            {
                class2 = new SmsResponseClass(new SmsClass(SmsItem.Number, currentMenuItem.More(this.MaxSmsBodyLength)));
            }
            else if (SmsItem.Body == currentMenuItem.BackKey)
            {
                this._stateList.RemoveAt(this._stateList.Count - 1);
                currentMenuItem = this.CurrentMenuItem;
                class2 = new SmsResponseClass(new SmsClass(SmsItem.Number, currentMenuItem.ToString(this.MaxSmsBodyLength)));
            }
            else if (SmsItem.Body == currentMenuItem.HomeKey)
            {
                this._stateList.Clear();
                class2 = new SmsResponseClass(new SmsClass(SmsItem.Number, this.ToString(this.MaxSmsBodyLength)));
            }
            else if (currentMenuItem[SmsItem.Body] != null)
            {
                this._stateList.Add(SmsItem.Body);
                currentMenuItem = currentMenuItem[SmsItem.Body];
                if (currentMenuItem.Type == MenuItemEnum.CustomString)
                {
                    class2 = new SmsResponseClass(new SmsClass(SmsItem.Number, currentMenuItem.ResponseString));
                    class2.SessionState = currentMenuItem.ResponseSessionState;
                }
                else if (currentMenuItem.Type == MenuItemEnum.CustomFunction)
                {
                    this._stateList.Add(SmsItem.Body);
                    class2 = currentMenuItem.CallCustomFunction(SmsItem);
                }
                else
                {
                    this._stateList.Add(SmsItem.Body);
                    this._moreCount = 0;
                    class2 = new SmsResponseClass(new SmsClass(SmsItem.Number, currentMenuItem.ToString(this.MaxSmsBodyLength)));
                }
            }
            else
            {
                class2 = new SmsResponseClass(new SmsClass(SmsItem.Number, currentMenuItem.ErrorMessage));
            }
            if (class2.SessionState == ResponseSessionStateEnum.Reset)
            {
                this._stateList.Clear();
                this._moreCount = 0;
            }
            return class2;
        }

        public string ToString(int MaxLength)
        {
            return this.GetString(MaxLength, 0);
        }

        private bool ValidKey(string CheckKey)
        {
            if (((this._Items == null) || (CheckKey == null)) || (this._MoreKey == CheckKey.Trim()))
            {
                return false;
            }
            for (int i = 0; i < this._Items.Count; i++)
            {
                if ((this._Items[i].Key == CheckKey.Trim()) || (this._Items[i].AltKey == CheckKey.Trim()))
                {
                    return false;
                }
            }
            return true;
        }

        public SmsMenuItem CurrentMenuItem
        {
            get
            {
                if (((this._stateList == null) || (this._stateList.Count == 0)) || (this._Items == null))
                {
                    return null;
                }
                SmsMenuItem item = this[this._stateList[0]];
                for (int i = 1; i < this._stateList.Count; i++)
                {
                    item = item[this._stateList[i]];
                    if (item == null)
                    {
                        return item;
                    }
                }
                return item;
            }
        }

        public string ErrorMessage
        {
            get
            {
                return this._ErrorString;
            }
            set
            {
                this._ErrorString = value;
            }
        }

        public string Footer
        {
            get
            {
                return this._footer;
            }
            set
            {
                this._footer = value;
            }
        }

        public string Header
        {
            get
            {
                return this._header;
            }
            set
            {
                this._header = value;
            }
        }

        public SmsMenuItem this[string MenuKey]
        {
            get
            {
                if (((this._Items != null) && (MenuKey != null)) && (MenuKey.Trim().Length != 0))
                {
                    for (int i = 0; i < this._Items.Count; i++)
                    {
                        if ((this._Items[i].Key == MenuKey) || (this._Items[i].AltKey == MenuKey))
                        {
                            return this._Items[i];
                        }
                    }
                }
                return null;
            }
        }

        public List<SmsMenuItem> Items
        {
            get
            {
                return this._Items;
            }
        }

        public string KeyTextSeparator
        {
            get
            {
                return this._keyTextSeparator;
            }
            set
            {
                this._keyTextSeparator = value;
            }
        }

        public int MaxSmsBodyLength
        {
            get
            {
                return this._MaxSmsBodyLength;
            }
            set
            {
                this._MaxSmsBodyLength = value;
            }
        }

        public int MoreCount
        {
            get
            {
                return this._moreCount;
            }
        }

        public string MoreKey
        {
            get
            {
                return this._MoreKey;
            }
            set
            {
                if ((value != null) && !this.ValidKey(value))
                {
                    throw new Exception("Error:Invalid Menu Key or Key already in use");
                }
                this._MoreKey = value;
            }
        }

        public object SmsMenuData
        {
            get
            {
                return this._menuData;
            }
            set
            {
                this._menuData = value;
            }
        }

        public List<string> StateList
        {
            get
            {
                return this._stateList;
            }
            set
            {
                this._stateList = value;
            }
        }
    }
}

